//
//  main.c
//  LinearStack
//
//  Created by Shawn on 2020/4/14.
//  Copyright © 2020 Shawn. All rights reserved.
//

//此工程用于演示顺序存储下的堆栈结构

#include "stdio.h"
#include "stdlib.h"
#include "math.h"

#define MAXSIZE 20

#define SUCCESS 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int ElementType;
typedef int Status;

typedef struct LinearStack {
    //    标志栈顶；特别的使用 -1 标志栈空；还能反映堆栈的长度
    int top;
    ElementType data[MAXSIZE];
}LinearStack;

/// 堆栈的初始化
/// @param s 堆栈
Status stackInit(LinearStack *s){
    s->top = -1;
    return SUCCESS;
}

/// 清空堆栈
/// @param s 堆栈
Status stackClear(LinearStack *s){
    //    清空堆栈的思想就是标志其他位置都未被使用就行了，并不需要对数据和空间进行操作。
    s->top = -1;
    return SUCCESS;
}

/// 判断堆栈是否为空
/// @param s 堆栈
Status stackIsEmpty(LinearStack s){
    return -1 == s.top;
}


/// 获取堆栈的长度
/// @param s 堆栈
int stackGetCount(LinearStack s){
    return 1 + s.top;
}


/// 遍历输出堆栈
/// @param s 堆栈
Status stackPrint(LinearStack s){
    printf("输出堆栈信息：");
    for (int i = 0; i < stackGetCount(s); i++) {
        printf("%d, ", s.data[i]);
    }
    printf("\n\n");
    return SUCCESS;
}

/// 压栈
/// @param s 堆栈
/// @param e 新元素
Status stackPush(LinearStack *s, ElementType e){
    if (MAXSIZE == stackGetCount(*s)) {
        printf("栈已经满了！\n");
        return ERROR;
    }else{
        //        栈顶 +1 ，并且将新的数据放入堆栈。
        s->data[++s->top] = e;
    }
    return SUCCESS;
}

/// 弹栈
/// @param s 栈
/// @param e 元素值带回
Status stackPop(LinearStack *s, ElementType *e){
    if (-1 == s->top) {
        printf("栈已经空了！\n");
        return ERROR;
    }else{
        //        取出当前元素带回，栈顶 -1。
        *e = s->data[s->top--];
    }
    return SUCCESS;
}

int main(int argc, const char *argv[]){
    
    
    LinearStack s;
    ElementType e;
    
    stackInit(&s);
    stackPrint(s);
    
    for (int i = 0; i < 10; i++) {
        stackPush(&s, i);
        stackPrint(s);
    }
    
    for (int i = 0; i < 10; i++) {
        stackPop(&s, &e);
        printf("出栈元素值为：%d,", e);
        stackPrint(s);
    }
}
